package controllers

import (
	"alarmservice/com"
	"alarmservice/model"
	"math/rand"
	"net/url"
	"strconv"
	"time"

	"github.com/astaxie/beego/validation"
	simplejson "github.com/bitly/go-simplejson"
)

//Login处理
type loginUserFormData struct {
	UserName string `valid:"Required"form:"username"`
	Password string `valid:"Required"form:"password"`
}

type LoginRegController struct {
	baseController
}

func (c *LoginRegController) PageLogin() {
	if c.Ctx.Request.Method == "GET" {
		c.loginGet()
	} else {
		c.loginPost()
	}
}

func (c *LoginRegController) loginGet() {
	c.TplName = "login.tpl"
}

func (c *LoginRegController) loginPost() {
	valid := validation.Validation{}

	u := loginUserFormData{}

	if err := c.ParseForm(&u); err != nil {
		c.Abort("500")
	}

	b, err := valid.Valid(&u)

	if err != nil {
		c.Abort("500")
	}

	if !b {
		c.Data["FormErrs"] = valid.Errors
		c.Get()
		return
	}

	adminUser, err := model.GetAdminUserByUserNamePass(u.UserName, u.Password)
	if err != nil {
		c.Data["Errors"] = err.Error()
		c.loginGet()
		return
	}

	//查询到用户信息了
	c.SetSession("uid", adminUser.Id)

	//跳转了
	c.Redirect("/", 302)
}

func (c *LoginRegController) PageReg() {
	uid := c.getUidByRegCode()
	if uid == 0 {
		c.Redirect("/login", 302)
		return
	}

	if c.Ctx.Request.Method == "GET" {
		c.regGet()
	} else {
		c.regPost()
	}

}

func (c *LoginRegController) regGet() {
	c.UseLayout()
	c.TplName = "reg.tpl"
}

func (c *LoginRegController) regPost() {
	fromUserId := c.getUidByRegCode()

	valid := validation.Validation{}

	adminUser := model.AdminUser{}

	if err := c.ParseForm(&adminUser); err != nil {
		c.Data["Errors"] = err.Error()
		c.regGet()
		return
	}

	b, err := valid.Valid(&adminUser)

	if err != nil {
		c.Abort("500")
	}

	repassword := c.GetString("repassword")
	if repassword != adminUser.Password {
		valid.SetError("repassword", "重复密码必须与原密码相同")
		b = false
	}

	//判断用户名是否存在
	_, err = model.GetAdminUserByUserName(adminUser.Username)
	if err == nil {
		valid.SetError("Username", "用户名已经存在")
		b = false
	}

	//XXX 应该还有检查手机和邮箱等联系方式是否重复

	if !b {
		mapFormErrs := com.ValidErrorToMapByField(valid.Errors)
		c.SetFormErrsToJson(mapFormErrs)
		c.regGet()
		return
	}

	//通过验证,开始插入数据
	adminUser.Password = com.Md5(adminUser.Password)
	adminUser.CreateTime = time.Now()
	adminUser.FromUserId = fromUserId
	err = model.Insert(adminUser)
	if err != nil {
		c.Abort("500")
	}

	//注册成功了，去掉regcode
	c.removeRegCode()
	c.Redirect("/login", 302)
}

//根据邀请码获取邀请用户的UID
func (c *LoginRegController) getUidByRegCode() int64 {
	paramName := "regcode"

	regCode := c.GetString(paramName)
	if regCode == "" {
		return 0
	}

	uidItem, ok := controllerCache.Get("regCode" + regCode)
	if !ok {
		return 0
	}

	return uidItem.(int64)
}

func (c *LoginRegController) removeRegCode() {
	regCode := c.GetString("regcode")
	if regCode == "" {
		return
	}

	controllerCache.Delete("regCode" + regCode)
}

func (c *LoginRegController) generateRegCode() string {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	n := r.Int63()

	regCode := com.Md5(strconv.FormatInt(n, 10))

	//缓存一小时
	controllerCache.Set("regCode"+regCode, c.AdminUser.Id, time.Second*3600)

	return regCode
}

type UserController struct {
	LoginRegController
}

func (c *UserController) NextPrepare() {
	c.NeedLogin = true
	c.UseLayout()
}

func (c *UserController) PageProfile() {
	if c.Ctx.Request.Method == "GET" {
		c.profileGet()
	} else {
		c.profilePost()
	}
}

func (c *UserController) profileGet() {
	_, ok := c.Data["PostAdminUserMap"]
	if !ok {
		c.Data["PostAdminUserMap"] = model.Obj2Map(c.AdminUser)
	}

	c.TplName = "user/profile.tpl"
}

func (c *UserController) profilePost() {
	valid := validation.Validation{}

	adminUser := model.AdminUser{}
	if err := c.ParseForm(&adminUser); err != nil {
		c.Data["Errors"] = err.Error()
		c.profileGet()
		return
	}

	postAdminUserMap := model.Obj2Map(adminUser)
	c.Data["PostAdminUserMap"] = postAdminUserMap

	valid.Required(adminUser.Name, "Name.Required")
	valid.MaxSize(adminUser.Name, 30, "Name.MaxSize")

	valid.Required(adminUser.Email, "Email.Required")
	valid.Email(adminUser.Email, "Email.Email")

	valid.Required(adminUser.Phone, "Phone.Required")
	valid.Numeric(adminUser.Phone, "Phone.Numeric")
	valid.MaxSize(adminUser.Phone, 20, "Phone.MaxSize")

	if valid.HasErrors() {
		mapFormErrs := com.ValidErrorToMapByField(valid.Errors)
		c.SetFormErrsToJson(mapFormErrs)
		c.profileGet()
		return
	}

	err := model.UpdateById(c.AdminUser.Id, adminUser, "name", "email", "phone")
	if err != nil {
		c.Abort("500")
		return
	}

	c.profileGet()
	//操作成功，信息提示
}

func (c *UserController) PagePassword() {
	if c.Ctx.Request.Method == "GET" {
		c.passwordGet()
	} else {
		c.passwordPost()
	}
}

func (c *UserController) passwordGet() {
	c.TplName = "user/editpassword.tpl"
}

func (c *UserController) passwordPost() {
	valid := validation.Validation{}
	oldPassword := c.GetString("oldpassword")
	newPassword := c.GetString("password")
	reNewPassword := c.GetString("repassword")

	valid.Required(oldPassword, "oldpassword.Required")
	valid.Required(newPassword, "password.Required")
	valid.Required(reNewPassword, "repassword.Required")

	if newPassword != reNewPassword {
		valid.SetError("repassword", "重复密码必须与设置密码相同")
	}

	if valid.HasErrors() {
		mapFormErrs := com.ValidErrorToMapByField(valid.Errors)
		c.SetFormErrsToJson(mapFormErrs)
		c.passwordGet()
		return
	}

	if model.AdminUserPasswordHash(oldPassword) != c.AdminUser.Password {
		valid.SetError("oldpassword", "密码错误")
	}

	if valid.HasErrors() {
		mapFormErrs := com.ValidErrorToMapByField(valid.Errors)
		c.SetFormErrsToJson(mapFormErrs)
		c.passwordGet()
		return
	}

	//修改密码

	err := model.UpdateById(c.AdminUser.Id, model.AdminUser{Password: model.AdminUserPasswordHash(newPassword)})
	if err != nil {
		c.Abort("500")
		return
	}

	//退出重新登录
	c.Redirect("/logout", 302)
}

//获取用户注册邀请码
func (c *UserController) PageAjaxInvite() {

	regCode := c.generateRegCode()
	url := "http://" + c.Ctx.Request.Host + "/reg?regcode=" + url.QueryEscape(regCode)
	c.Data["json"] = com.ApiSucc(url)
	c.ServeJSON()
	return
}

func (c *UserController) PageLogout() {
	c.SetSession("uid", nil)
	c.Redirect("/login", 302)
}

func (c *UserController) PageAjaxGetUsersByNameUserName() {
	if c.Uid == 0 {
		c.returnJson(com.ApiUnknowFailed("not login"))
		return
	}

	keyWord := c.GetString("k", "")
	if keyWord != "" {
		keyWord = keyWord + "%"
	}

	users := make(model.MapAdminUser)
	var err error

	if keyWord != "" {
		err = model.Orm.Cols("id", "username", "name").Where("`username` LIKE ? OR `name` LIKE ?", keyWord, keyWord).Limit(10).Find(&users)
	} else {
		err = model.Orm.Cols("id", "username", "name").Limit(10).Find(&users)
	}

	if err != nil {
		c.returnJson(com.ApiUnknowFailed("select error"))
		return
	}

	j := simplejson.New()
	j.SetPath(make([]string, 0), model.MapIntKeyToStr(users))
	c.returnJson(com.ApiSucc(j))
	return
}
